/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <stddef.h>
#include <stdint.h>

namespace El {

constexpr uint32_t CHANNEL_MAX = 1;
constexpr uint32_t CHANNEL_STREAM_TYPE_MAX = 2;

enum MEDIA_VIDEO_ENC_STREAM : uint32_t {
    MEDIA_VIDEO_ENC_STREAM_MAIN = 0,       ///< 主码流
    MEDIA_VIDEO_ENC_STREAM_EXTRA1,         ///< 辅码流1
    MEDIA_VIDEO_ENC_STREAM_EXTRA2,         ///< 辅码流2
    MEDIA_VIDEO_ENC_STREAM_EXTRA3,         ///< 辅码流3
    MEDIA_VIDEO_ENC_STREAM_EXTRA4,         ///< 辅码流4
    MEDIA_VIDEO_ENC_STREAM_SNAPSHOT,       ///< 抓大图
    MEDIA_VIDEO_ENC_STREAM_SMALL_SNAPSHOT, ///< 抓小图
    MEDIA_VIDEO_ENC_STREAM_NUMBER          ///< 种类数
};

enum MEDIA_FRAME_TYPE : uint32_t {
    MEDIA_FRAME_UNKOWN = 0,
    MEDIA_FRAME_I,
    MEDIA_FRAME_P,
    MEDIA_FRAME_B,
    MEDIA_FRAME_MJPEG,
    MEDIA_FRAME_JPEG,
    MEDIA_FRAME_PCM,
    MEDIA_FRAME_AAC,
    MEDIA_FRAME_G711A,
    MEDIA_FRAME_G711U,
    MEDIA_FRAME_OPUS,
    MEDIA_FRAME_MSG,
    MEDIA_FRAME_NUM
};

enum MEDIA_VIDEO_CODEC_TYPE : uint32_t {
    MEDIA_VIDEO_CODEC_UNKOWN = 0,
    MEDIA_VIDEO_CODEC_H264,
    MEDIA_VIDEO_CODEC_H265,
    MEDIA_VIDEO_CODEC_MPEG4,
    MEDIA_VIDEO_CODEC_MPEG2,
    MEDIA_VIDEO_CODEC_MPEG1,
    MEDIA_VIDEO_CODEC_NUM
};

enum MEDIA_AUDIO_CODEC_TYPE : uint32_t {
    MEDIA_AUDIO_CODEC_UNKOWN = 100,
    MEDIA_AUDIO_CODEC_AAC,
    MEDIA_AUDIO_CODEC_G711A,
    MEDIA_AUDIO_CODEC_G711U,
    MEDIA_AUDIO_CODEC_MP3,
    MEDIA_AUDIO_CODEC_OPUS,
    MEDIA_AUDIO_CODEC_NUM
};

enum MEDIA_AUDIO_ENC_PACK_TYPE : uint32_t {
    MEDIA_AUDIO_ENC_PACK_RAW = 0, ///< 原始数据
    MEDIA_AUDIO_ENC_PACK_PS,      ///< PS流格式打包
    MEDIA_AUDIO_ENC_PACK_NUM
};

enum MEDIA_VIDEO_ENC_PACK_TYPE {
    MEDIA_VIDEO_ENC_PACK_ES = 0, ///< ES流,原始流
    MEDIA_VIDEO_ENC_PACK_PS,     ///< PS流
    MEDIA_VIDEO_ENC_PACK_CM,     ///< 自定义封装
    MEDIA_VIDEO_ENC_PACK_NUM
};

/// 音频编码格式
struct AudioEncFormat {
    MEDIA_AUDIO_CODEC_TYPE codecType;
    int32_t sampleRate;
    int32_t depth; ///< 采样位深: 支持8位，16位
    int32_t channels;
    int32_t packetPeriod;
    MEDIA_AUDIO_ENC_PACK_TYPE pack;
};

/// 音频编码包
struct AudioEncPacket {
    uint8_t *buf;      ///< 数据
    uint32_t len;      ///< 数据长度
    uint64_t pts;      ///< 时间戳，微秒
    uint32_t seq;      ///< 帧序号
    uint8_t newFormat; ///< 编码格式是否变更，0：未变动，1：已变动
    uint64_t utc;      ///< UTC,微秒
    int32_t sampleRate;
    int32_t channels;
    MEDIA_FRAME_TYPE frameType;       /// 帧类型
    MEDIA_AUDIO_CODEC_TYPE codecType; ///< 音频编码类型
};

/// 视频编码格式
struct VideoEncFormat {
    MEDIA_VIDEO_CODEC_TYPE codecType;
    int32_t width;
    int32_t height;
    double fps;
};

/// 视频编码包
struct VideoEncPacket {
    uint8_t *buf;                       /// 帧数据
    uint32_t len;                       /// 帧数据长度
    uint64_t pts;                       /// 时间戳，微秒
    uint32_t seq;                       /// 帧序号，用于校验是否丢帧
    MEDIA_FRAME_TYPE frameType;         /// 帧类型
    uint64_t utc;                       /// UTC,微秒
    uint16_t width;                     /// 该帧编码数据的宽度
    uint16_t height;                    /// 该帧编码数据的长度
    double fps;                   /// 帧率
    MEDIA_VIDEO_ENC_PACK_TYPE packType; /// 该数据包的封装格式
    MEDIA_VIDEO_CODEC_TYPE codecType;   /// 编码类型
};

} // namespace El